var app = angular.module ( 'formCustSqlViewApp' );

/**
 * 自定义列表 列表页面
 * list-page
 * @param $compile
 * @param $timeout
 * @param $injector
 * @param listService
 * @param baseService
 * @returns
 */
app.directive ( 'listPage' , function ( $compile , $timeout , $injector , listService , baseService ) {

	return {
	    restrict : 'E' ,
	    scope : {
	        listScope : "=" ,
	        dialogScope : "=" ,
	        parent : "=" ,
	        pName : "=" ,
	        noSee : "=" ,
	        noDel : "=" ,
	        noEdit : "="
	    } ,
	    templateUrl : "../../../form/formCustSql/view/listPage.html" ,
	    replace : true ,
	    transclude : true ,
	    compile : function ( elm , attrs ) {

		    var parent = elm.scope ( );
		    return function ( scope , elm , attrs ) {

			    scope.listService = listService;
			    listService.scope = scope;

			    scope.formCustSqlViewService = $injector.get ( "formCustSqlViewService" );
			    scope.base = baseService;
			    scope.formCustSqlViewService.scope = scope;

			    scope.formCustSqlViewService.bindParent ( scope , 'list' , scope.pName , function ( ) {

				    scope.vo = scope.parent.vo;
				    scope.listScope = scope;
				    scope.parent.listScope = scope;
				    scope.parent.listService = listService;
				    scope.selectType = getDataByKey(scope.parent.vo.expand,"selectType");

				    scope.__id = scope["__listId"];

				    // 重新渲染list
				    scope.$on ( "reBindList" , function ( ) {

					    listService.reBindList ( scope );
				    } );

				    listService.setListPageHeight ( scope.parent );
				    listService.setFieldsCount ( scope );
			    } );

		    };
	    }
	};
} );

app.service ( 'listService' , [ '$compile' , '$injector' , 'baseService', 'checkService' , function ( $compile , $injector , baseService, checkService ) {

	var service = {
	    reBindList : function ( scope ) {

		    this.listCallback ( {
			    list : scope.list
		    } , scope );
	    } ,
	    listCallback : function ( data , scope ) {

		    scope = scope || this;
		    
		    scope.parent.listScope.list = data.list;
		    
		    // 获取每个字段的值
		    scope.listService.setData ( scope , data );

		    // 获取总计数据
		    scope.listService.setSumData ( scope , data );

		    // scope.listService.fixToolBar ( scope );
	    } ,
	    setData : function ( scope , data ) {

		    var list = data.list;
		    // 如果没有数据,则返回
		    if ( !list || list.length == 0 ) {
			    return;
		    }
		    var fields = scope.parent.fields;
		    var service = scope.listService;
		    for ( var j = 0 ; j < fields.length ; j++ ) {
			    fields[j].tdData = [ ];
		    }
		    for ( var j = 0 ; j < fields.length ; j++ ) {
			    for ( var i = 0 ; i < list.length ; i++ ) {
				    var dataJson = scope.listService.getTdata ({
				    	tempItem:list[i] , 
				    	field:fields[j] ,
				    	type:'sql' ,
				    	pindex:i , 
				    	index:j , 
				    	scope:scope 
				    });
				    fields[j].tdData.push ( dataJson.t );// 将转换后的值存入这里
				    if ( dataJson.bindHtml ) {
					    fields[j].bindHtml = true;
				    }
			    }
		    }

	    } ,
	    // 获取总计数据
	    setSumData : function ( scope , data ) {

		    var sumData = data.sumData;
		    // 如果不存在统计,则返回
		    if ( !sumData || !scope.needSumFields || scope.needSumFields.length == 0 )
			    return;
		    for ( var i = 0 ; i < scope.needSumFields.length ; i++ ) {
			    var fields = scope.needSumFields[i];
			    fields.val = sumData[fields.fieldName];
		    }
	    } ,
	    getTotal : function ( list , fieldName ) {

		    if ( !list || list.length == 0 || !fieldName )
			    return;
		    var count = 0;
		    for ( var i = 0 ; i < list.length ; i++ ) {
			    count += parseFloat ( list[i][fieldName] || 0 );
		    }
		    // 精度省略 , 如果超过三位,则保留三位
		    count = count + "";
		    var exp = count.split ( "\." )[1];
		    if ( exp && exp.length > 3 ) {
			    count = parseFloat ( count ).toFixed ( 3 );
		    }
		    return count;

	    } ,
	    getPer : function ( list , fieldName ) {

		    if ( !list || list.length == 0 || !fieldName )
			    return;
		    var count = this.getTotal ( list , fieldName );
		    return ( count / list.length ).toFixed ( 2 );
	    } ,
	    getMax : function ( list , fieldName ) {

		    if ( !list || list.length == 0 || !fieldName )
			    return;
		    var max = list[0][fieldName];
		    for ( var i = 0 ; i < list.length ; i++ ) {
			    if ( max < list[i][fieldName] ) {
				    max = list[i][fieldName];
			    }
		    }
		    return max;
	    } ,
	    getMin : function ( list , fieldName ) {

		    if ( !list || list.length == 0 || !fieldName )
			    return;
		    var min = list[0][fieldName];
		    for ( var i = 0 ; i < list.length ; i++ ) {
			    if ( min > list[i][fieldName] ) {
				    min = list[i][fieldName];
			    }
		    }
		    if ( isStrNull ( min ) ) {
			    return "空";
		    }
		    return min;
	    } ,
	    selectAllData : function ( checked , list , scope ) {
		    if ( !list )
			    return;
		    for ( var i = 0 ; i < list.length ; i++ ) {
			    list[i].idchecked = checked;
		    }
		    scope.listService.getSelectCount ( scope , list );
	    } ,
	    onDataClick : function ( scope , list , data , index ) {

		    if ( scope.selectType == 1 ) { // 单选
			    for ( var i = 0 ; i < list.length ; i++ ) {
				    list[i].idchecked = ( i == index );
			    }
		    } else {
			    data.idchecked = !data.idchecked;
		    }
		    this.getSelectCount ( scope , list );
	    } ,
	    getSelectCount : function ( scope , list ) {

//		    if ( !list || !scope.selectType ) {
//			    scope.selectCount = 0;
//			    return;
//		    }
		    // 统计选中的行数
		    var count = 0;
		    for ( var i = 0 ; i < list.length ; i++ ) {
			    if ( list[i].idchecked ) {
				    count++;
			    }
		    }
		    scope.selectCount = count;
	    } ,
	    orderByFn : function ( scope , item ) {

		    if ( item.sortAble == 1 ) {
			    scope.parent.pageParams = scope.parent.pageParams || {};
			    scope.pageParams = scope.parent.pageParams || {};
			    if ( scope.pageParams.params ) {
				    scope.pageParams.params = JsonUtil.ps ( scope.pageParams.params );
			    }
			    scope.pageParams.params = scope.pageParams.params || {};

			    var sorts = [ "asc" , "desc" ];
			    var orderBy = scope.pageParams.params['orderBy'];
			    var oldOrderBy = orderBy;
			    var hasOrdered = false;
			    if ( orderBy ) {
				    orderBy = orderBy.split ( "," );
				    for ( var i = 0 ; i < orderBy.length ; i++ ) {
					    var temp = orderBy[i].split ( "#" );
					    if ( temp[0] == item.fieldName ) {
						    hasOrdered = true;
						    orderBy.splice ( i , 1 );
						    oldOrderBy = orderBy.join ( "," );
						    orderBy = temp;
						    break;
					    }
				    }
			    }
			    orderBy = hasOrdered ? orderBy : "";
			    var sortIndex = 0;
			    if ( hasOrdered ) {
				    sortIndex = ( orderBy[1] == sorts[0] ) ? 1 : 0;
			    }
			    item.sortDir = sorts[sortIndex];
			    orderBy = item.fieldName + "#" + sorts[sortIndex];
			    if ( oldOrderBy ) {
				    orderBy = oldOrderBy + "," + orderBy;
			    }
			    scope.pageParams.params.orderBy = orderBy;
			    scope.pageParams.params = JSON.stringify ( scope.pageParams.params );
		    }
	    } ,
	    mutiDeleteData : function ( scope ) {

		    var list = scope.list;
		    var idList = new Array ( );
		    for ( var i = 0 ; i < list.length ; i++ ) {
			    if ( list[i].idchecked ) {
				    idList.push ( getDataByKey ( list[i] , scope.parent.expand.crudPkName ) );
			    }
		    }
		    if ( idList.length == 0 ) {
			    $.Dialog.error ( "请选择数据~" );
			    return;
		    }

		    var params = {
		        alias : scope.parent.vo.alias ,
		        dataId : idList.join ( "," )
		    };
		    this.deleteAjax ( params , scope.parent );
	    } ,
	    // 删除数据
	    deleteData : function ( scope , data , index ) {

		    var parent = scope.parent;
		    if ( parent.isSub ) {
			    parent.listScope.list.splice ( index , 1 );
			    // parent.listScope.list.splice(index,1);
		    } else {
			    var params = {
			        alias : parent.vo.alias ,
			        dataId : getDataByKey ( data , parent.expand.crudPkName )
			    };
			    this.deleteAjax ( params , parent );
		    }
	    } ,
	    exportData : function ( scope , type ) {

		    var page = scope.pageScope.page;
		    var size = type == 0 ? page.count : page.pageSize;
		    page.pageNum = type == 1 ? page.pageNum : 1;
		    var params = {
		        curPage : page.pageNum ,
		        pageSize : size
		    };
		    if ( scope.pageScope.params ) {
			    // searchScope.initHeighting = true;
			    params = angular.extend ( {} , params , scope.pageScope.params );
		    }
		    // 如果有控制显隐列,那么就要把字段传回去
		    if ( scope.parent.expand.canHidden == 1 ) {
			    var fieldNames = [ ];
			    for ( var i = 0 ; i < scope.parent.fields.length ; i++ ) {
				    if ( scope.parent.fields[i].hidden != 1 ) {
					    fieldNames.push ( scope.parent.fields[i].fieldName );
				    }
			    }
			    if ( fieldNames.length == 0 ) {
				    alert ( "请至少选择导出一个字段" );
				    return;
			    }
			    params.fieldColumns = fieldNames.join ( "," );
		    }
		    this.postAcForm ( {
		        url : scope.parent.vo.exportUrl ,
		        param : params ,
		        callback : function ( data ) {
			        if ( data ) {
				        $.Dialog.success ( "导出成功" );
			        } else {
				        $.Dialog.error ( "导出失败!" );
			        }
		        }
		    } );
	    } ,
	    // 同步提交表单请求
	    postAcForm : function ( option) {
	    	var url = option.url;
	    	var param = option.param;
	    	var callback = option.callback;
            var form = $ ( '<form method="post" action="' + url + '" style="display:none;"></form>' );
            // 设置表单参数
            function setInputEl ( json , name ) {
                name = name ? name + "." : "";
                for ( var i in json ) {
                    if ( json[i] instanceof Array ) {
                        for ( var j = 0 ; j < json[i].length ; j++ ) {
	                        setInputEl ( json[i][j] , name + i + "[" + j + "]" );
                        }
                    } else if ( json[i] instanceof Date ) {
                        var input = $ ( "<input type='text' name='" + name + i + "'/>" );
                        input.val ( json[i] );
                        form.append ( input );
                    } else if ( json[i] instanceof Object ) {
                        setInputEl ( json[i] , name + i );
                    } else {
                        var input = $ ( "<textarea type='text' name='" + name + i + "'/>" );
                        input.val ( json[i] );
                        form.append ( input );
                    }
                }
            }
            setInputEl ( param );
        	document.body.appendChild(form[0]); // chrom 56 之后必须要将form加入到body中
            form.submit ( );
            form.remove();
            return;
	    } ,
	    toggleField : function ( scope , item ) {

		    item.hidden = !item.hidden
		    this.setFieldsCount ( scope );
	    } ,
	    setFieldsCount : function ( scope ) {

		    var count = 0;
		    var parent = scope.parent;
		    for ( var i = 0 ; i < parent.fields.length ; i++ ) {
			    var field = parent.fields[i];
			    if ( !field.hidden ) {
				    count++;
			    }
		    }
		    // 如果有选择框,则+1
		    if ( scope.selectType ) {
			    count++;
		    }
		    // 如果有序号,则+1
		    if ( parent.vo.showRowsNum ) {
			    count++;
		    }
		    count++;// 操作栏
		    scope.fieldsCount = count;
	    } ,
	    setListPageHeight : function ( parent ) {

		    var isTree = parent.isTree;
		    var treeScope = parent.treeScope;
		    var searchScope = parent.searchScope;
		    var listId = parent.listScope.__id;
		    var listEl = $ ( "#" + listId );
		    var pageEl = $ ( "#page_" + listId ).hide ( );
		    var that = this;
		    window.setTimeout ( function ( ) {

			    // 判断search模块和树形模块是否加载出来
			    if ( searchScope && listEl[0] && ( ( !isTree ) || ( isTree && treeScope ) ) ) {
				    var searchId = searchScope.__searchId;
				    var searchEl = $ ( "#" + searchId );
				    if ( searchEl[0] && !searchEl.is ( ":hidden" ) ) {
					    var searchHeight = searchEl.height ( ) + 20;
					    listEl.css ( {
						    height : "calc( 100% - " + searchHeight + "px )"
					    } );
					    pageEl.show ( );
				    } else {
					    that.setListPageHeight ( parent );
				    }

			    } else {
				    that.setListPageHeight ( parent );
			    }
		    } , 100 );

	    } ,
	    replaceUrl : function ( url , param ) {

		    if ( !url ) {
			    return "";
		    }
		    var hrefnew = url;
		    // 替换${}
		    var p1 = /\#\{(\w+)\}/g;
		    try {
			    var vars = hrefnew.match ( p1 );
			    for ( var i = 0 ; i < vars.length ; i++ ) {
				    var keyt = vars[i];
				    var p2 = /\#\{(\w+)\}/g;
				    var key = p2.exec ( keyt );
				    hrefnew = hrefnew.replace ( keyt , param[key[1]] );
			    }
		    } catch ( ex ) {}
		    // 替换#{}
		    p1 = /\$\{(\w+)\}/g;
		    try {
			    var vars = hrefnew.match ( p1 );
			    for ( var i = 0 ; i < vars.length ; i++ ) {
				    var keyt = vars[i];
				    var p2 = /\$\{(\w+)\}/g;
				    var key = p2.exec ( keyt );
				    hrefnew = hrefnew.replace ( keyt , param[key[1]] );
			    }
		    } catch ( ex ) {}
		    // 替换{}
		    p1 = /\{(\w+)\}/g;
		    try {
			    var vars = hrefnew.match ( p1 );
			    for ( var i = 0 ; i < vars.length ; i++ ) {
				    var keyt = vars[i];
				    var p2 = /\{(\w+)\}/g;
				    var key = p2.exec ( keyt );
				    hrefnew = hrefnew.replace ( keyt , param[key[1]] );
			    }
		    } catch ( ex ) {}
		    return hrefnew;
	    },
	    openNewWindow : function(url){
	    	if ( url && !url.startWith ( "/" ) && !url.startWith ( "www" ) && !url.startWith ( "http" )  ) {
	    		url = "/" + url;
		    }
    		if ( url.startWith ( "/" ) ) {
			    // 获取路径
			    var path = window.location.pathname.split ( "/" )[1];
			    url = "/" + path + url;
		    }
	    	window.open(url);
	    },
	    // 详情跳转
	    detailJump : function ( field , data ) {
		    if ( !field.href ) {
			    return;
		    }
		    
		    // 从字段扩展中获取href点击类型
		    field.expand = JsonUtil.ps(field.expand) || {};
		    var hrefSetting = field.expand.hrefSetting || {};
		    var openType = hrefSetting.openType + "";
		    var width = hrefSetting.width || "100";
		    var height = hrefSetting.height || "100";
		    var widthUnit = hrefSetting.widthUnit=="px"?"":"%";
		    var heightUnit = hrefSetting.heightUnit=="px"?"":"%";
		    
		    var name = field.tdData[data.$index];
		    
		    // 替换链接
		    var href = this.replaceUrl(field.href,data);
		    
		    switch ( openType ) {
			    case "3" : // 普通对话框
			    case "4" : // TOP对话框
			    	if ( href && !href.startWith ( "/" ) && !href.startWith ( "www" ) && !href.startWith ( "http" )  ) {
			    		href = "/" + href;
				    }
				    var conf = {
						height : height+heightUnit,
						width :  width+widthUnit,
				        url : href ,
				        title : name ,
				        topOpen : openType == "4"
				    };
				    jQuery.Dialog.open ( conf );
			    break;
			    case "5" : // 新页面
		    		this.openNewWindow(href);
			    break;
			    case "2" : // 标签页/tab页
			    default : 
			    	// 如果是单独的页面,则直接打开新窗口
			    	if(!top.addTab){
			    		this.openNewWindow(href);
			    		return;
			    	}
			    	if ( href && href.startWith ( "/" ) ) {
			    		href = href.substring ( "0" , href.length );
				    }
				    top.addTab ( {
				        id : name,
				        name : name ,
				        icon : "fa-align-justify" ,
				        url : href ,
				        closable : true
				    } )
			    break;
		    }

	    },
	    /*** 获取格式化后的列表数据*/
	    getTdata : function (options) {

	    	var tempItem = options.tempItem;
		    var field = options.field;
		    var type = options.type;
		    var pindex = options.pindex;
		    var index = options.index;
		    var scope = options.scope;
	    	
		    if ( !tempItem )
			    return;
		    
		    var lowFieldName = field.fieldName;
		    var item = tempItem;
		    var val = getValByScope ({
    		    scope : item ,
    		    exp : lowFieldName
		    });

		    // 单位替换
		    if ( field.unit ) {
			    val = eval ( "(function(){" + field.unit + "})()" );
			    return {
			        o : val ,// 原始值
			        t : val // 转换后的值
			    };
		    }

		    if ( !val && val!==0 ) {
			    return {
			        o : val ,// 原始值
			        t : val // 转换后的值
			    };
		    }
		    
		    if ( field.dataType == "date" || field.dataType == "datetime" || field.dataType == "timestamp" ) {
			    if ( field.dateFormat && val ) {
				    if ( val.time ) {
					    return {
					        o : new Date ( val.time ).format ( field.dateFormat ) ,// 原始值
					        t : new Date ( val.time ).format ( field.dateFormat )  // 转换后的值
					    };
				    }
				    if(typeof val == "number"){
				    	return {
					        o : val ,// 原始值
					        t : new Date (val).format ( field.dateFormat ) // 转换后的值
					    };
				    }
				    return {
				        o : val ,// 原始值
				        t : new Date ( (val + "" ).replaceAll ( "-" , "/" ) ).format ( field.dateFormat ) // 转换后的值
				    };
			    }
		    }

		    return this.getData ({
		    	 field:field , 
		    	 val:val  , 
		    	 scope:scope  , 
		    	 tempItem:tempItem  
		    });
	    } ,
	    getData : function (options) {
		    var field = options.field;
		    var val = options.val;
		    var scope = options.scope;
		    var tempItem = options.tempItem;
		    switch ( field.controlType ) {
			    case 1 :// 单行文本
				    return {
				        o : val ,// 原始值
				        t : val // 转换后的值
				    };
			    case 4 :// 下拉框
			    case 6 :// 单选框
			    // case 8 :// 下拉框多选
				    if ( field.dateFormat && field.dateFormat[val] ) {
					    return {
					        o : val ,// 原始值
					        t : field.dateFormat[val] // 转换后的值
					    };
				    }
				    return {
				        o : val ,// 原始值
				        t : val // 转换后的值
				    };
			    case 5 :// 下拉框字典
			    case 7 :// [字典]单选框
				    if ( field.dateFormat ) {
					    var rtObj = {
					        o : val ,
					        t : val
					    };
					    checkService.getDicByCode ( field.dateFormat , function ( json ) {

						    if ( json ) {
							    rtObj.t = json[val];
						    }
					    } );
					    return rtObj;
				    }
				    return {
				        o : val ,// 原始值
				        t : val
				    // 转换后的值
				    };
			    case 8 :// 复选框
				    if ( field.dateFormat && !isStrNull ( val ) ) {
					    var tempVal = "";
					    if( typeof val == "string" ){
					    	val = val.split ( "," );
					    }
					    for ( var i = 0 ; i < val.length ; i++ ) {
						    tempVal = tempVal + ( field.dateFormat[val[i]] || val[i] ) + ",";
					    }
					    return {
					        o : val ,// 原始值
					        t : tempVal.substring ( 0 , tempVal.length - 1 )
					    // 转换后的值
					    };
				    }
				    return {
				        o : val ,// 原始值
				        t : val
				    // 转换后的值
				    };
				    ;
			    case 9 :// 复选框 字典
				    if ( field.dateFormat && !isStrNull ( val ) ) {
					    var rtObj = {
					        o : val ,
					        t : val
					    };
					    checkService.getDicByCode( field.dateFormat , function ( json ) {

						    var tempVal = "";
						    val = val.split ( "," );
						    for ( var i = 0 ; i < val.length ; i++ ) {
							    tempVal = tempVal + ( json[val[i]] || val[i] ) + ",";
						    }
						    rtObj.t = tempVal.substring ( 0 , tempVal.length - 1 );
					    } );
					    return rtObj;
				    }
				    return val;
			    case 3 :// 日期类型
				    if ( field.dateFormat && angular.isDate ( val ) ) {
					    return {
					        o : val ,// 原始值
					        t : new Date ( val ).format ( field.dateFormat )
					    // 转换后的值
					    };
				    }
				    return {
				        o : val ,// 原始值
				        t : val // 转换后的值
				    };
			    case 5 :// 数据字典
				    var data = checkService.getDicByCode( field.dateFormat , function ( data ) {

					    return {
					        o : val ,// 原始值
					        t : ( data && data[val] ) || val // 转换后的值
					    };
				    } );
				    if ( data ) {
					    return {
					        o : val ,// 原始值
					        t : ( data && data[val] ) || val // 转换后的值
					    };
				    }
				    // return val;
			    break;
			    case 10 :// JSON
		    		return {
		    			o : val ,// 原始值
		    			t : getDataByKey(val,field.dateFormat)// 转换后的值
		    		};
			    	break;
			    default :
				    return {
				        o : val ,// 原始值
				        t : val
				    // 转换后的值
				    };
		    }
	    }
	};
	return service;
} ] );
// 可以格式化
